<template>
	<div class="chat-container">
		<van-nav-bar
				class="custom-navbar">
			<template #left>
				<van-icon name="arrow-left" class="nav-icon" @click="backRoute" />
			</template>
			<template #title>
				<span class="nav-title">{{navTitle}}</span>
			</template>
			<template #right v-if=" group == 1">
				<van-icon name="ellipsis" class="nav-icon" @click="toGroupInformation" />
			</template>
		</van-nav-bar>

		<!-- 消息列表 -->
		<div
				class="message-list"
				ref="messageList">
			<div
					class="message-item"
					v-for="msg in messages"
					:key="msg.id"
					:class="msg.senderId == userId ? 'sent' : 'received'">
				<!-- 消息容器（左右分栏） -->
				<div class="message-container">
					<!-- 左侧头像 -->
					<div
							class="avatar"
							:class="msg.senderId == userId ? 'right' : 'left'">
						<img
								:src="msg.avatar"
								@click="previewImage(msg.avatar)"
								alt="">
					</div>

					<!-- 右侧消息详情 -->
					<div
							class="message-details"
							:class="msg.senderId == userId ? 'sent' : 'received'">
						<!-- 消息头部 -->
						<div class="message-header">
							<span
									class="identity"
									:class="msg.senderId == userId ? 'sent' : 'received'">
								{{ msg.senderId == userId  ? msg.sendTime + ' 我' : msg.realname + ' ' + msg.sendTime }}
							</span>
						</div>

						<!-- 消息气泡 -->
						<div
								class="bubble"
								:class="msg.senderId == userId ? 'sent' : 'received'">
							<div
									class="read-status"
									v-if="group == 0 && msg.senderId == userId"
									:class="msg.read ? 'read' : 'unread'">
								{{ msg.read ? '已读' : '未读' }}
							</div>

							<!-- 文本消息 -->
							<div
									v-if="msg.contextType === 'text'"
									class="text-content"
									v-html="renderMessage(msg.message)">
							</div>

							<!-- 图片消息 -->
							<div
									v-else-if="msg.contextType === 'image'"
									class="image-content">
								<van-image
										fit="cover"
										:src="msg.fileName"
										@click="previewImage(msg.fileName)"
								/>
							</div>

							<!-- 文件消息 -->
							<div
									v-else-if="msg.contextType === 'file'"
									class="file-content"
									@click="downloadFile(msg)">
								<div class="file-info">
									<div class="file-name">{{ msg.message }}</div>
									<div class="file-size">{{ msg.fileSize }}</div>
								</div>
								<div class="file-icon">
									<van-icon
											name="link-o"
											size="24px"/>
								</div>

							</div>

							<!-- 语音消息 -->
							<div
									v-else-if="msg.contextType === 'voice'"
									class="voice-content"
									@click="playVoice(msg)">
								<div class="voice-wave">
									<div
											v-for="i in 5"
											:key="i"
											class="wave-bar"
											:class="{ active: isPlaying && currentVoice === msg.id && i <= activeBars }"></div>
								</div>
								<div class="voice-duration">
									{{ msg.duration }}"
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<!-- 输入工具栏 -->
		<div class="input-toolbar">
			<!-- 语音图标 -->
			<van-icon
					name="volume-o"
					size="18px"
					:color="isVoiceInput ? '#07c160' : '#666'"
					class="icon-btn"
					@touchstart="startVoiceRecording"
					@touchend="stopVoiceRecording"
					@touchcancel="cancelVoiceRecording"
					@mousedown="startVoiceRecording"
					@mouseup="stopVoiceRecording"
					@mouseleave="cancelVoiceRecording"/>

			<!-- 输入框 -->
			<div class="input-field-container">
				<!-- 可编辑的div -->
				<div
						ref="messageInput"
						class="message-input"
						contenteditable="true"
						@input="handleInput"
						@keydown="handleKeydown"
						@paste="handlePaste"
						@focus="showPlaceholder = false"
						@blur="saveSelection"
						:data-placeholder="showPlaceholder ? '输入消息' : ''"
				></div>
			</div>

			<van-icon
					name="photo-o"
					size="18px"
					color="#666"
					class="icon-btn"
					@click="addImage"/>
			<van-icon
					name="upgrade"
					size="18px"
					color="#666"
					class="icon-btn"
					@click="addFile"/>

			<van-icon
					name="smile-o"
					size="18px"
					color="#666"
					class="icon-btn"
					@click="toggleEmojiPicker"/>


			<!-- 发送按钮 -->
			<van-button
					class="send-btn"
					type="primary"
					@click="sendTextMessage">发送</van-button>
		</div>

		<!-- 表情面板容器 -->
		<div
				v-show="showEmojiPicker"
				class="emoji-panel-container"
				:style="{ bottom: inputToolbarHeight + 'px' }">
			<div class="emoji-panel">
				<div class="emoji-picker">
					<div
							v-for="(emoji, index) in emojiList"
							:key="index"
							class="emoji-item"
							@click="selectEmoji(emoji)">
						<img :src="emoji.src" :alt="emoji.title" class="emoji-img">
					</div>
				</div>
			</div>
		</div>

		<VoiceRecord ref="voiceRecordRef" v-if="showVoiceRecord" :visible="showVoiceRecord"  @send="sendVoice" />

		<chat-uploader
				v-model="imageName"
				v-show="false"
				placeholder="请选择图片"
				ref="imgUploaderRef"
				type="image"
				multiple
				style="margin-left: 5px;margin-top: 5px">
		</chat-uploader>

		<chat-uploader
				v-model="fileName"
				v-show="false"
				placeholder="请选择文件"
				ref="fileUploaderRef"
				type="file"
				multiple
				style="margin-left: 5px;margin-top: 5px">
		</chat-uploader>

		<!-- 图片预览 -->
		<van-image-preview
				v-model="showImagePreview"
				:images="previewImages"/>
	</div>
</template>

<script>
	import {
		postAction,
		uploadAction,
		getFileAccessHttpUrl
	} from '@/api'
	import { randomUUID, formatTime } from '@/util/util.js'
	import mqHandler from './util/mqHandler'
	import ChatUploader from '@//components/ChatUploader'
	import Vue from 'vue'
	import VoiceRecord from './util/voiceRecord.vue'
	import emojiData from './util/emoji.js';


	export default {
		components:{
			ChatUploader,
			VoiceRecord
		},
		data() {
			return {
				navTitle: '',
				userId: this.$store.getters.userid,
				messages: [],
				newMessage: '',
				newMessageType:null,
				isVoiceInput: false,
				recordingDuration: 0,    // 录音时长
				recordingTimer: null,    // 录音计时器
				showVoiceRecord: false,
				showImagePreview: false,
				previewImages: [],
				isPlaying: false,
				currentVoice: null,
				playAudio:null,
				activeBars: 3,
				waveInterval: null,
				group: 0,
				toContactId: null,
				currentContact: null,
				groupUserIds: [],
				imageName:null,
				fileName:null,
				fileSize:null,
				isLongPress: false,    // 是否满足长按条件
				pressTimer: null,    // 长按计时器
				isRecording: false,    // 是否正在录音
				enterFlag:true,    // 首次加载消息列表
				showEmojiPicker: false,    // 控制表情面板显示
				emojiList: [],    // 表情列表
				showPlaceholder: true,
				lastSelection: null,
				inputToolbarHeight: 50    // 初始输入工具栏高度
			}
		},
		watch: {
			imageName(newVal) {
				if (newVal && newVal !== "") {
					this.newMessageType = 'image'
					this.fileName = newVal.split(',')[0];
					this.fileSize = this.formatFileSize(newVal.split(',')[1])
					this.newMessage = newVal.split(',')[0]
					this.sendTextMessage()
					this.fileName = null
					this.fileSize = null
				}
			},
			fileName(newVal) {
				if (newVal && newVal !== "") {
					const [name, size] = newVal.split(',');
					this.fileName = name;
					this.fileSize = this.formatFileSize(size);
					this.newMessage = name;

					// 图片后缀检测
					const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.ico'];
					const isImage = imageExtensions.some(ext =>
							name.toLowerCase().endsWith(ext)
					);

					// 根据文件类型设置消息类型
					this.newMessageType = isImage ? 'image' : 'file';
					this.sendTextMessage()
					this.fileName = null
					this.fileSize = null
				}
			}
		},
		created() {
			this.toContactId = this.$route.path.substring(this.$route.path.lastIndexOf('/') + 1)
			this.getCurrentContact()
			this.initMessageList()
			if(this.unread || 1 == 1){
				this.zeroUnread(this.toContactId,0)
			}
			this.loadEmojis()
			this.initMQListener()
		},
		mounted() {
			// 添加样式到页面
			const style = document.createElement('style');
			style.innerHTML = `
				.message-input[data-placeholder]:empty:before {
					content: attr(data-placeholder);
					color: #999;
				}
			`;
			document.head.appendChild(style);

		},
		beforeDestroy() {
			if (this.pressTimer) clearTimeout(this.pressTimer);
			if (this.recordingTimer) clearInterval(this.recordingTimer);
			if (this.waveInterval) clearInterval(this.waveInterval)
		},
		methods: {
			toGroupInformation() {
				this.$router.push({
				name: 'groupInformation',
				params: {
					groupId: this.toContactId,
					navTitle: this.navTitle
				}
				});
			},
			// 计算输入工具栏高度
			calculateInputToolbarHeight() {
				const toolbar = this.$el.querySelector('.input-toolbar');
				if (toolbar) {
					this.inputToolbarHeight = toolbar.offsetHeight;
				}
			},
			// 处理输入事件
			handleInput() {
				this.newMessage = this.getEditableContent();
				this.adjustInputHeight();
				this.calculateInputToolbarHeight();
			},

			// 处理键盘事件
			handleKeydown(event) {
				// 处理Ctrl+Enter发送
				if (event.key === 'Enter' && event.ctrlKey) {
					event.preventDefault();
					this.sendTextMessage();
				}
				// 处理普通Enter键（换行）
				else if (event.key === 'Enter' && !event.shiftKey) {
					event.preventDefault();
					this.insertNewLine();
				}
			},

			// 处理粘贴事件
			handlePaste(event) {
				event.preventDefault();
				const text = (event.clipboardData || window.clipboardData).getData('text');
				document.execCommand('insertText', false, text);
			},

			// 处理失去焦点事件
			saveSelection() {
				const input = this.$refs.messageInput;
				if (input) {
					const selection = window.getSelection();
					if (selection.rangeCount > 0) {
						this.lastSelection = selection.getRangeAt(0);
					}
				}
				if (!this.getEditableContent().trim()) {
					this.showPlaceholder = true;
				}
			},
			// 恢复选区
			restoreSelection() {
				const input = this.$refs.messageInput;
				if (!input || !this.lastSelection) return;

				const selection = window.getSelection();
				selection.removeAllRanges();
				selection.addRange(this.lastSelection.cloneRange());
			},

			// 插入换行
			insertNewLine() {
				document.execCommand('insertLineBreak');
				this.adjustInputHeight();
			},
			// 调整输入框高度
			adjustInputHeight() {
				const input = this.$refs.messageInput;
				if (!input) return;

				// 重置高度
				input.style.height = 'auto';

				// 计算新高度（限制最大高度）
				const maxHeight = 500;
				const scrollHeight = input.scrollHeight;

				if (scrollHeight > maxHeight) {
					input.style.height = maxHeight + 'px';
					input.style.overflowY = 'auto';
				} else {
					input.style.height = scrollHeight + 'px';
					input.style.overflowY = 'hidden';
				}
			},
			// 获取可编辑区域内容
			getEditableContent() {
				return this.$refs.messageInput.innerHTML;
			},
			// 渲染消息内容（替换表情标记）
			renderMessage(content) {
				// 转义HTML特殊字符
				let safeContent = content
						.replace(/&/g, "&amp;")
						.replace(/</g, "&lt;")
						.replace(/>/g, "&gt;")
						.replace(/"/g, "&quot;")
						.replace(/'/g, "&#039;");

				// 替换表情标记为图片
				this.emojiList.forEach(emoji => {
					const regex = new RegExp(`\\[${emoji.title}\\]`, 'g');
					safeContent = safeContent.replace(
							regex,
							`<img src="${emoji.src}" alt="${emoji.title}" class="message-emoji" style="width: 24px;height: 24px;vertical-align: middle;margin: 0 2px;display: inline-block;">`
					);
				});

				return safeContent;
			},
			loadEmojis() {
				// 从emojiData中提取表情列表
				this.emojiList = emojiData[0].children;
			},
			// 打开/关闭表情面板
			toggleEmojiPicker() {
				this.showEmojiPicker = !this.showEmojiPicker;
				if (this.showEmojiPicker) {
					this.calculateInputToolbarHeight();
				}
			},

			// 选择表情
			selectEmoji(emoji) {
				this.showEmojiPicker = false;

				const input = this.$refs.messageInput;
				if (!input) return;

				// 确保输入框获得焦点并恢复选区
				input.focus();
				this.$nextTick(() => {
					this.restoreSelection();

					// 如果恢复选区失败，则将光标移到末尾
					const selection = window.getSelection();
					if (selection.rangeCount === 0 || selection.getRangeAt(0).collapsed === false) {
						const range = document.createRange();
						range.selectNodeContents(input);
						range.collapse(false);
						selection.removeAllRanges();
						selection.addRange(range);
					}

					// 创建表情图片元素
					const img = document.createElement('img');
					img.src = emoji.src;
					img.width = 24;
					img.height = 24;
					img.alt = emoji.title;
					img.className = 'message-emoji';
					img.dataset.emoji = emoji.title;

					// 插入表情
					const range = selection.getRangeAt(0);
					range.deleteContents();
					range.insertNode(img);

					// 移动光标到表情后
					const newRange = document.createRange();
					newRange.setStartAfter(img);
					newRange.collapse(true);
					selection.removeAllRanges();
					selection.addRange(newRange);

					// 更新状态
					this.newMessage = this.getEditableContent();
					this.showPlaceholder = false;
					this.adjustInputHeight();
					this.calculateInputToolbarHeight();

					// 保存新的选区
					this.saveSelection();

					// 触发输入事件
					const event = new Event('input', { bubbles: true });
					input.dispatchEvent(event);
				});
			},
			// 开始长按（按下）
			startVoiceRecording() {
				// 清除可能存在的计时器
				if (this.pressTimer) clearTimeout(this.pressTimer)

				console.log("触碰录音按钮")
				// 设置新的计时器
				this.pressTimer = setTimeout(() => {
					this.isLongPress = true;
					this.startRealRecording();
				}, 500); // 0.5秒后触发
			},
			// 实际开始录音
			startRealRecording() {
				if (this.isRecording || this.showVoiceRecord) return;
				console.log("满足长按条件，开始录音");
				this.isRecording = true;
				this.isVoiceInput = true;

				// 显示录音组件
				this.showVoiceRecord = true;
				this.$nextTick(() => {
					if (this.$refs.voiceRecordRef) {
						this.$refs.voiceRecordRef.startRecorder();
						// 启动计时器
						this.recordingTimer = setInterval(() => {
							this.recordingDuration++;
						}, 1000);
					}
				});
			},
			// 停止长按
			stopVoiceRecording() {
				// 清除计时器（防止0.5秒内松开）
				clearTimeout(this.pressTimer);
				// 如果已经进入录音状态
				if (this.isLongPress && this.isRecording) {
					console.log("录音结束");
					this.stopRealRecording();
				}
				// 重置状态
				this.isLongPress = false;
			},
			// 实际停止录音
			stopRealRecording() {
				clearInterval(this.recordingTimer);
				if (this.$refs.voiceRecordRef) {
					this.$refs.voiceRecordRef.stopRecorder();

					if(this.recordingDuration <= 0)	return;
					this.$refs.voiceRecordRef.submit();
				}
				this.isRecording = false;
				this.isVoiceInput = false;
				this.recordingDuration = 0;
			},
			// 取消按压
			cancelVoiceRecording() {
				// 清除计时器
				clearTimeout(this.pressTimer);

				// 如果已经开始录音则停止
				if (this.isRecording) {
					console.log("录音取消");
					this.cancelRealRecording();
				}
				// 重置状态
				this.isLongPress = false;
				this.showVoiceRecord = false;
			},
			// 实际取消录音
			cancelRealRecording() {
				clearInterval(this.recordingTimer);

				if (this.$refs.voiceRecordRef) {
					this.$refs.voiceRecordRef.stopRecorder();
				}
				this.isRecording = false;
				this.isVoiceInput = false;
				this.recordingDuration = 0;
			},
			addImage() {
				const uploader = this.$refs.imgUploaderRef;
				const fileInput = uploader.$el.querySelector('input[type="file"]');
				if (fileInput) {
					fileInput.click();
				}
			},
			addFile() {
				const uploader = this.$refs.fileUploaderRef;
				const fileInput = uploader.$el.querySelector('input[type="file"]');
				if (fileInput) {
					fileInput.click();
				}
			},
			initMessageList() {
				postAction('/sys/chat/message/list', {
					num: 0,
					size: -1, //查所有
					toContactId: this.$route.path.substring(this.$route.path.lastIndexOf('/') + 1),
					userId: this.$store.getters.userid
				}).then((res) => {
					var _list = res.result;
					_list.forEach((e) => {
						e.fileName = e.fileName != null ? getFileAccessHttpUrl(e.message) : ""
						e.fileSize = this.formatFileSize(e.fileSize)
						e.avatar = e.avatar != null ? getFileAccessHttpUrl(e.avatar) : '/static/mobile/img/common/user_default.webp'
						e.realname = e.realname != null ? e.realname : this.navTitle
						e.sendTime = formatTime(e.sendTime)
						this.unread = !this.unread && !e.read

					});
					this.messages = _list
					console.log("获取消息列表:", _list)
					if (this.enterFlag){
						this.$nextTick(() => {
							this.scrollToBottom();
						});
						this.enterFlag = false 	// 初次加载消息列表时滑动到底部
					}

				}).catch((err) => {
					console.error('获取消息列表失败:', err)
				})
			},
			initMQListener() {
				console.log("监听新消息:" )
				Vue.prototype.$bus.$on('message',this.handleNewMessage)
				if (this.group == 0){
					console.log("监听消息是否已读:")
					Vue.prototype.$bus.$on('chanMessageRead',this.initMessageList)
				}
			},
			getCurrentContact() {
				postAction('/sys/chat/relative', {
					type: "meeting",
					userId: this.$store.getters.userid,
					goalId: this.toContactId,
				}).then((res) => {
					if (res.success) {
						this.currentContact = res.result
						this.navTitle = this.currentContact.displayName
						if (this.currentContact.is_group == 1) {
							this.group = 1
							this.getGroupUserList(this.currentContact.goalId)
						}
					} else {
						console.error('加载聊天对象失败:', res.message);
					}
				}).catch((err) => {
					console.error('加载聊天对象异常:', err);
				});
			},
			handleNewMessage(message) {
				if (message.type != 'OneToGroup'){
					// 判断是否是当前用户的消息
					if (message.receiveid !== this.userId) return;
				}
        // var value={
        //       "id": "a0132ab6-2f4f-4ffb-86d4-c119dc264e22",
        //       "senderId": "1962785644347965440",
        //       "receiverId": "1839562113857626113",
        //       "message": message.info.msgcontent,
        //       "sendTime": "2025-09-02 16:52:56",
        //       "contextType": "text",
        //       "voice": "",
        //       "duration": 0,
        //       "fileName": null,
        //       "fileSize": null,
        //       "fromUserId": "1962785644347965440",
        //       "realname": "个人机器人",
        //       "avatar":  '/static/mobile/img/common/user_default.webp',
        //       "is_group": 0,
        //       "read": true
        //     }
        // this.messages.push(value)
        // this.$nextTick(() => {
        //   this.scrollToBottom();
        // });
				this.initMessageList();
				if (this.toContactId == message.sendid  ){
					this.zeroUnread(this.toContactId, 0)
				}
			},
			backRoute() {
				Vue.prototype.$bus.$off('message', this.handleNewMessage)
				Vue.prototype.$bus.$off('chanMessageRead', this.initMessageList)
				this.$router.push({
					name: 'chat'
				})
			},
			// 发送语音消息
			sendVoice(duration, file) {
				if (!file || duration <= 0) {
					this.showVoiceRecord = false;
					return
				}
				let msg = {
					content: URL.createObjectURL(file),
					contentFile: file,
					fromUser: this.$store.getters, //
					senduserid: this.userId,
					senduserAvatar: this.$store.getters.avatar,
					senduserRealname: this.$store.getters.nickname,
					id: randomUUID(), //
					toContactId: this.toContactId,
					type: 'voice',
					sendTime: new Date().getTime(),
					status: 'going',
					isPlay: 0, //
					extends: {
						duration: duration,
					},
					is_group: this.group,
					groupUserIds: this.groupUserIds,
				}

				var fileSize = msg.contentFile.size;
				var fileName = msg.contentFile.name;
				var formData = new FormData();
				formData.append('file', msg.contentFile);

				uploadAction('/sys/common/upload2', formData).then((res) => {
					if(!res.success){
						this.$toast('文件上传失败')
						return
					}
					console.log("🚀 ~ file: chat.vue:720 ~ uploadAction ~ this.getFileAccessHttpUrl(res):", getFileAccessHttpUrl(res.message))
					postAction('/sys/chat/message/sendUser', {
						message: res.message,	//消息内容
						senduserId: msg.senduserid,		//发起人id
						senduserRealname: msg.senduserRealname,		//发起人名字
						senduserAvatar: msg.senduserAvatar,		//发起人头像
						recipientid: msg.toContactId,		//接收人
						type: msg.type,		//消息类型
						duration: msg.extends.duration,		//语音时长
						isGroup: msg.is_group, 		//是否是群聊
						groupUserIds: msg.groupUserIds, 	//群聊用户id（不包括自己）
						fileSize,
						fileName
					}).then((res) => {
						if(!res.success){
							this.$toast('消息发送失败')
							return
						}
						console.log("🚀 ~ file: chat.vue:738 ~ }).then ~ res:", res)
						this.initMessageList()
						//	mq发消息
						if(msg.is_group == 1){
							// if(msg.toContactId == "1871841717772664832"){
							// 	that.toWXChat(msg,2);
							// }
							//	群聊消息
							mqHandler.send({
								channelid: res.result.id,
								type: 'OneToGroup',
								sendid: msg.toContactId,
								receiveid: msg.groupUserIds,
								info: {
									infotype: msg.type,
									realname: msg.senduserRealname,
									avatar: msg.senduserAvatar,
									msgcontent: res.result.message,
									duration: msg.extends.duration,
									fileSize,
									fileName
								},
								time: new Date().toLocaleString().replace(/\//g, '-'),
								timestamp: new Date().getTime()
							})
						}else if(msg.is_group == 0){
							mqHandler.send({
								channelid: res.result.id,
								type: 'OneToOne',
								sendid: msg.senduserid,
								receiveid: msg.toContactId,
								info: {
									infotype: msg.type,
									realname: msg.senduserRealname,
									avatar:  msg.senduserAvatar,
									msgcontent: res.result.message,
									duration: msg.extends.duration,
									fileSize,
									fileName
								},
								time: new Date().toLocaleString().replace(/\//g, '-'),
								timestamp: new Date().getTime()
							})
						}
					})
					this.showVoiceRecord = false;
				}).catch((err) => {
					console.error('语音发送失败:', err);
				});
				this.scrollToBottom()
			},
			// 发送消息（修改后的方法）
			sendTextMessage() {
				const content = this.getEditableContent();
				if (!content.trim() && !this.$refs.messageInput.querySelector('img')) return;

				// 将表情图片转换为标记文本
				let message = content;
				const emojiImages = this.$refs.messageInput.querySelectorAll('img.message-emoji');
				emojiImages.forEach(img => {
					const emojiMark = `[${img.dataset.emoji}]`;
					message = message.replace(img.outerHTML, emojiMark);
				});

				this.newMessage = message;
				this.newMessageType = 'text';

				// 实际发送逻辑（使用原有的发送方法）
				this.originalSendTextMessage();

				// 清空输入框
				this.$refs.messageInput.innerHTML = '';
				this.showPlaceholder = true;
				this.adjustInputHeight();
				this.calculateInputToolbarHeight();
			},
			//	发送文字、图片、文件消息
			originalSendTextMessage() {
				if (!this.newMessage.trim()) return
				const newMsg = {
					id: Date.now(),
					senderId: this.userId,
					type: this.newMessageType ? this.newMessageType : 'text',
					message: this.newMessage,
					sendTime: this.formatTime(),
					realname: this.$store.getters.nickname,
					avatar: this.$store.getters.avatar,
					fileName: this.fileName,
					fileSize: this.fileSize
				}

				//文字消息
				postAction('/sys/chat/message/sendUser', {
					message: newMsg.message, 	//消息内容
					senduserId: newMsg.senderId, 	//发起人id
					senduserRealname: newMsg.realname, 		//发起人名字
					senduserAvatar: newMsg.avatar,		 //发起人头像
					recipientid: this.toContactId, 		//接收人
					type: newMsg.type,		 //消息类型
					duration: 0,	 //语音时长
					isGroup: this.group,	 //是否是群聊
					groupUserIds: this.groupUserIds ,	//群聊用户id（不包括自己）
					fileName: newMsg.fileName,
					fileSize: newMsg.fileSize
				}).then((res) => {
					console.log("🚀 ~ file: chat.vue:843 ~ }).then ~ res:", res)
					if (!res.success) {
						this.$toast('消息发送失败')
						return
					}
					this.initMessageList()
					//mq发消息
					if (this.group == 1) {
						//群聊消息
						var allId = []
						console.log("🚀 ~ file: chat.vue:853 ~ sendTextMessage ~ allId:", allId)
						console.log("🚀 ~ file: chat.vue:854 ~ sendTextMessage ~ allId:", this.toContactId)
						mqHandler.send({
							channelid: res.result.id,
							type: 'OneToGroup',
							sendid: this.toContactId,
							groupid: this.toContactId,
							groupname: this.navTitle,
							avatar: this.currentContact.avatar,
							receiveid: this.groupUserIds,
							info: {
								infotype: newMsg.type,
								realname: newMsg.realname,
								avatar: newMsg.avatar,
								msgcontent: newMsg.message,
								duration: 0,
								fileName: newMsg.fileName,
								fileSize: newMsg.fileSize
							},
							time: new Date().toLocaleString().replace(/\//g, '-'),
							timestamp: new Date().getTime()
						})
					} else if (this.group == 0) {
						//单聊消息
						console.log("发送消息:", this.newMessage)
						mqHandler.send({
							channelid: res.result.id,
							type: 'OneToOne',
							sendid: this.userId,
							receiveid: this.toContactId,
							info: {
								infotype: newMsg.type,
								realname: newMsg.realname,
								avatar: newMsg.avatar,
								msgcontent: newMsg.message,
								duration: 0,
								fileName: newMsg.fileName,
								fileSize: newMsg.fileSize
							},
							time: new Date().toLocaleString().replace(/\//g, '-'),
							timestamp: new Date().getTime()
						}, (error, result) => {
							if (error) {
								console.error("消息发送失败:", error);
							} else {
								console.log("消息发送成功:", result);
								this.newMessage = ""; // 清空发送框
							}
						});
					}
				}).catch((err) => {
					console.error('消息发送失败:', err);
				});
				this.newMessage = ''
				this.$nextTick(() => {
					const input = this.$refs.messageInput;
					if (input) {
						input.style.height = 'auto';
					}
					this.calculateInputToolbarHeight();
				});
				this.scrollToBottom()
			},
			//获取群用户列表
			getGroupUserList(id) {
				const that = this
				postAction("/sys/chat/member/getGroupMember/", {
					groupId: that.toContactId
				}).then(res => {
					that.groupUser = []
					console.log("🚀 ~ file: chat.vue:923 ~ getAction ~ res:", res)
					var list = res.result
					list.forEach(item => {
						if (item.memberId !== that.userId) {
							that.groupUserIds.push(item.memberId)
						}

						that.groupUser.push({
							id: item.id,
							group_id: item.groupId,
							user_id: item.memberId,
							role: item.role,
							unread: item.unread,
							userInfo: {
								id: item.memberId,
								displayName: item.realname,
								avatar: getFileAccessHttpUrl(item.avatar)
							}
						})
					})
					that.group_id = id
					console.log("🚀 ~ file: chat.vue:944 ~ getGroupUserList ~ that.groupUser:", that.groupUser)
				}).catch((err) => {
					console.log('err :>> ', err);
				})
			},
			//消息未读数改为0
			zeroUnread(toContactId, unread) {
				//减去消息未读总数
				unread = unread == 0 ? 1 : unread;
				console.log(unread)
				postAction("/sys/chat/relative/zeroUnread", {
					goalId: toContactId,
					myId: this.userId
				}).then(res => {
					console.log("🚀 ~ file: chat.vue:958 ~ zeroUnread ~ res:", res)
					mqHandler.send({
						channelid: '12138',
						type: 'OneToOneRead',
						sendid: this.userId,
						receiveid: toContactId,
						info: {},
						time: new Date().toLocaleString().replace(/\//g, '-'),
						timestamp: new Date().getTime()
					})
				})
			},
			scrollToBottom() {
				this.$nextTick(() => {
					const container = this.$refs.messageList;
					if (container && container.scrollHeight > 0) {
						container.scrollTop = container.scrollHeight;
					}
				});
			},
			formatTime() {
				const date = new Date()
				return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`
			},
			previewImage(imageUrl) {
				this.previewImages = [imageUrl]
				this.showImagePreview = true
			},
			downloadFile(msg) {
				var url = msg.fileName
				// window.open(url)
				fetch(url) //使用fetch函数发送一个GET请求到指定的URL，获取文件的响应对象。
						.then(response => response.blob()) //通过.then方法链，将响应对象转换为Blob数据（文件的二进制数据）。
						.then(blob => { //再次使用.then方法链，处理获取到的Blob数据。
							const link = document.createElement('a'); //使用document.createElement创建一个<a>节点。
							link.href = URL.createObjectURL(
									blob); //通过URL.createObjectURL方法，将Blob数据转换成URL对象，然后将该URL赋值给link的href属性。这一步相当于生成了一个临时URL，供下载使用。
							link.download = msg.message; // 替换为你要保存的文件名和扩展名(设置用户下载文件时使用的文件名和扩展名)
							link.click(); //调用click方法模拟用户点击链接，从而触发浏览器的文件下载行为。
							URL.revokeObjectURL(link.href); // 释放URL对象资源(使用URL.revokeObjectURL方法释放之前创建的URL对象资源，避免内存泄漏)
						})
						.catch(error => {
							console.error('下载失败:', error);
						});
				console.log('下载文件:', msg.message)
				this.$toast(`开始下载: ${msg.message}`)
			},
			playVoice(msg) {
				if (this.isPlaying && this.currentVoice === msg.id) {
					// 停止播放
					this.isPlaying = false
					if (this.playAudio) {
						this.playAudio.pause()
					}
					this.currentVoice = null
					clearInterval(this.waveInterval)
					return
				}

				if (this.isPlaying && this.currentVoice !== msg.id) {
					// 停止播放
					this.isPlaying = false
					if (this.playAudio) {
						this.playAudio.pause()
						this.playAudio = null
					}
					this.currentVoice = null
					clearInterval(this.waveInterval)
				}

				// 开始播放
				this.isPlaying = true
				this.currentVoice = msg.id

				// 语音播放逻辑
				this.playAudio = new Audio(getFileAccessHttpUrl(msg.message));
				this.playAudio.play(); //播放这个音频对象
				// 模拟声波动画
				this.activeBars = 3
				this.waveInterval = setInterval(() => {
					this.activeBars = Math.floor(Math.random() * 4) + 2
				}, 300)
				setTimeout(() => {
					this.isPlaying = false
					this.currentVoice = null
					clearInterval(this.waveInterval)
				}, msg.duration * 1000)
			},
			formatFileSize(bytes) {
				if (!bytes) return '0 B'
				if (bytes.includes('B')) return bytes
				const sizes = ['B', 'KB', 'MB', 'GB']
				const i = Math.floor(Math.log(bytes) / Math.log(1024))
				return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i]
			}
		}
	}
</script>

<style scoped>
	.custom-navbar {
		background-color: #fff;
		box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
	}

	.nav-title {
		font-size: 16px;
		font-weight: bold;
		color: #26B1A1;
		letter-spacing: 0.5px;
	}

	.van-nav-bar .van-icon {
		color: #26B1A1;
		font-size: 16px;
	}

	.chat-container {
		display: flex;
		flex-direction: column;
		height: 100vh;
		background-color: white;
		position: relative;
	}

	.message-list {
		flex: 1;
		overflow-y: auto;
		padding: 10px;

	}

	.message-item {
		display: flex;
		margin-bottom: 15px;
	}

	.message-item.received {
		flex-direction: row;
	}

	.message-item.sent {
		flex-direction: row-reverse;
	}

	.message-container {
		display: flex;
		flex-direction: row;
		max-width: 80%;
		min-width: 40%;
		position: relative;
	}

	.avatar {
		width: 48px;
		height: 48px;
		border-radius: 20%;
		overflow: hidden;
		margin: 4px;
		flex-shrink: 0;
	}

	.avatar img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.message-details {
		display: flex;
		flex-direction: column;
		position: relative;
		margin: 0 8px;
	}

	.message-header {
		font-size: 13px;
		color: #999;
		padding: 0 0px;
		margin-bottom: 4px;
	}

	.identity {
		display: inline-block;
	}

	.identity.sent {
		color: #999;
	}

	.identity.received {
		color: #999;
	}

	.bubble {
		position: relative;
		padding: 8px 12px;
		border-radius: 16px;
		font-size: 14px;
		line-height: 1.5;
		word-wrap: break-word;
		max-width: 100%;
	}

	.bubble.sent {
		background: linear-gradient(90deg, #26B1A1, #6FD0B3);
		color: white;
		border-bottom-left-radius: 4px;
	}

	.bubble.received {
		background-color: #fff;
		color: #333;
		border-bottom-right-radius: 4px;
		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
	}

	.message-item.sent .message-container {
		margin-left: auto;
	}

	.message-item.sent .avatar.right {
		order: 1;
		margin-left: 8px;
		margin-right: 0;
		background-color: #fff;
	}

	.input-toolbar {
		display: flex;
		align-items: flex-end;
		padding: 8px;
		background-color: #fff;
		box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.1);
		position: relative;
		z-index: 10;
	}

	.icon-btn {
		padding: 4px;
		background: transparent;
		border: none;
		cursor: pointer;
		transition: all 0.2s;
		margin-bottom: 6px;
	}

	.icon-btn:active {
		opacity: 0.7;
		transform: scale(0.95);
	}

	.send-btn {
		min-width: 60px;
		height: 32px;
		font-size: 14px;
		flex-shrink: 0;
		background: linear-gradient(90deg, #26B1A1, #6FD0B3);
		border-radius: 12.5%;
		margin-left: 6px;
		margin-right: 6px;
		margin-bottom: 6px;
	}

	.message-item.sent .message-details {
		align-items: flex-end;
	}

	/* 文本消息样式 */
	.text-content {
		white-space: pre-wrap;
		word-break: break-word;
	}

	/* 图片消息样式 */
	.image-content {
		border-radius: 8px;
		overflow: hidden;
		max-width: 200px;
	}

	/* 文件消息样式 */
	.file-content {
		display: flex;
		align-items: center;
		padding: 8px;
		background: rgba(255, 255, 255, 0.2);
		border-radius: 8px;
	}

	.file-icon {
		margin-right: 10px;
		color: inherit;

	}

	.file-info {
		display: flex;
		flex-direction: column;
	}

	.file-name {
		font-weight: 500;
		font-size: 14px;
		word-wrap: break-word; /* 允许长单词换行 */
		white-space: pre-wrap; /* 保留空格并允许换行 */
		word-break: break-word; /* 优先单词换行，必要时截断 */
		max-width: 150px; /* 保留最大宽度限制 */
	}

	.file-size {
		font-size: 12px;
		opacity: 0.8;
	}

	/* 语音消息样式 */
	.voice-content {
		display: flex;
		align-items: center;
		padding: 8px 12px;
	}

	.voice-wave {
		display: flex;
		align-items: flex-end;
		height: 24px;
		margin-right: 8px;
	}

	.wave-bar {
		width: 3px;
		height: 10px;
		margin: 0 2px;
		background-color: currentColor;
		border-radius: 2px;
		transition: height 0.3s ease;
	}

	.wave-bar.active {
		height: 20px;
	}

	.voice-duration {
		font-size: 14px;
		font-weight: 500;
	}

	/* 发送方语音消息特殊样式 */
	.bubble.sent .voice-wave .wave-bar {
		background-color: white;
	}

	/* 接收方语音消息特殊样式 */
	.bubble.received .voice-wave .wave-bar {
		background: linear-gradient(90deg, #26B1A1, #6FD0B3);
	}

	/* 已读未读状态样式 */
	.bubble .read-status {
		position: absolute;
		top: 2px;
		left: -30px;
		font-size: 11px;
		line-height: 1.2;
		z-index: 1;
	}

	.bubble.sent .read-status.read {
		color: #26B1A1; /* 已读状态颜色 */
	}

	.bubble.sent .read-status.unread {
		color: #999; /* 未读状态灰色 */
	}

	.message-details {
		position: relative;
		margin-top: 4px; /* 为状态显示留出空间 */
	}

	.message-item.received .message-details {
		margin-top: 0;
	}

	/* 文本消息容器 */
	.text-content {
		display: inline;
	}

	/* 表情面板容器 */
	.emoji-panel-container {
		position: absolute;
		bottom: 68px;
		left: 0;
		right: 0;
		height: 210px;
		z-index: 1000;
		background: #f8f8f8;
		border-top: 1px solid #eee;
		box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
		transition: transform 0.3s ease;
	}

	.emoji-panel {
		height: 100%;
		overflow: hidden;
	}

	.emoji-picker {
		display: grid;
		grid-template-columns: repeat(8, 1fr); /* 每行8个表情 */
		gap: 8px;
		padding: 12px;
		height: 100%;
		overflow-y: auto;
	}

	.emoji-item {
		display: flex;
		justify-content: center;
		align-items: center;
		cursor: pointer;
		transition: transform 0.2s;
	}

	.emoji-item:active {
		transform: scale(1.2);
	}

	.emoji-img {
		width: 32px;
		height: 32px;
		object-fit: contain;
	}

	.message-input {
		width: 100%;
		min-height: 24px;
		max-height: 500px;
		padding: 0px 8px;
		font-size: 14px;
		line-height: 1.5;
		border: none;
		outline: none;
		background: transparent;
		overflow-y: auto;
		white-space: pre-wrap;
		word-break: break-word;
	}

	.message-input:focus {
		outline: none;
	}

	.input-field-container {
		flex: 1;
		display: flex;
		align-items: center;
		background-color: #f5f5f5;
		border-radius: 18px;
		margin: 0 8px;
		padding: 0 4px;
		min-height: 36px;
		max-height: 500px;
	}

</style>
